' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
' ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
' THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
' PARTICULAR PURPOSE.
'
' Copyright (c) 2006 Microsoft Corporation. All rights reserved.

' Original code from the Microsoft Windows SDK for Windows Vista.

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports Microsoft.Feeds.Interop

' Provides feeds using the Vista RSS platform if available, but can fall
' back to using default feeds from resources.
Public Class FeedList
    Private _rssFeeds As List(Of RssFeed)
    Private _currentFeedIndex As Integer
    Private _currentItemIndex As Integer
    Private _lastRefresh As DateTime

    Friend Shared ReadOnly ImageExtensions As List(Of String) = _
        New List(Of String)(New String() {"*.BMP", "*.GIF", "*.PNG", "*.JPG", "*.JPEG"})

    Public Sub New()
        Me._lastRefresh = DateTime.MinValue
        Me._currentFeedIndex = -1
        Me._currentItemIndex = -1
    End Sub


    Public Sub Refresh()
        If Me._lastRefresh = DateTime.MinValue Then
            ' Load the common feed list.
            Load()
            Return
        End If

        ' Exposes methods that provide access to the Common Feed List, 
        ' which is a hierarchy of Really Simple Syndication (RSS) feeds 
        ' to which the user is subscribed.
        Dim fs As FeedsManager = New FeedsManager()

        Try
            Dim folder As IFeedFolder = CType(fs.GetFolder(""), IFeedFolder)
            For Each feed As IFeed In CommonFeedListUtils.LastWriteSince(folder, Me._lastRefresh)
                Dim rssFeed As RssFeed = Nothing
                Try
                    ' This feed was updated or is new, let's get it.
                    rssFeed = rssFeed.FromApi(feed)
                Catch ex As System.Runtime.InteropServices.COMException
                    System.Diagnostics.Debug.Print("Failed to get RSS feed '{0}' from API; skipping feed. Error: {1} ", feed.Name, ex.ToString())
                    Continue For ' Skip this feed.
                End Try

                ' If the feed has no items with picture enclosures then skip it.
                If rssFeed Is Nothing OrElse rssFeed.Items.Count = 0 Then
                    System.Diagnostics.Debug.Print("Feed '{0}' does not have any picture enclosures; skipping feed.", feed.Name)
                    Continue For
                End If

                ' Before we add it let's see if we have an old version of the feed.
                Dim index As Integer = _rssFeeds.IndexOf(feed)
                If index = -1 Then
                    ' This must be a new feed, let's append it to the list.
                    Me._rssFeeds.Add(rssFeed)
                Else
                    ' We have an existing feed with the same path. Let's insert it 
                    ' where the previous feed is at.
                    Me._rssFeeds.Insert(index, rssFeed)

                    ' Remove previous feed.
                    Me._rssFeeds.RemoveAt(index + 1)

                    ' Assure that current indexes are not out of bounds.
                    ValidateIndexes()
                End If
            Next feed
        Finally
            GC.Collect() ' Release all COM objects and their file handles.
            Me._lastRefresh = DateTime.Now
        End Try
    End Sub

    Public Sub Load()
        Dim loadstart As DateTime = DateTime.Now
        Dim newRssFeeds As List(Of RssFeed) = New List(Of RssFeed)()

        Try
            Dim fs As FeedsManager = New FeedsManager()
            Dim folder As IFeedFolder = CType(fs.GetFolder(""), IFeedFolder)
            For Each feed As IFeed In CommonFeedListUtils.CommonFeedList(folder)
                System.Diagnostics.Debug.Print("Found feed {0} with {1} items.", feed.Name, (CType(feed.Items, IFeedsEnum)).Count)
                Try
                    Dim rssFeed As RssFeed = rssFeed.FromApi(feed)

                    ' Only add this feed if it contains items
                    If Not rssFeed Is Nothing Then
                        System.Diagnostics.Debug.Print("Feed has {0} items with enclosures.", rssFeed.Items.Count)
                        If rssFeed.Items.Count > 0 Then
                            newRssFeeds.Add(rssFeed)
                        End If
                    Else
                        System.Diagnostics.Debug.Print("Feed is null.")
                    End If
                Catch ex As System.Runtime.InteropServices.COMException
                    System.Diagnostics.Debug.Print("Failed to get RSS feed '{0}' from API; skipping feed. Error: {1} ", feed.Name, ex.ToString())
                    ' Ignore exception, meaning ignore this feed and continue with next feed.
                End Try
            Next feed
        Finally
            ' Collect garbage so that all the COM objects are released which 
            ' closes the backing structured storage files.
            GC.Collect()
        End Try

        If newRssFeeds.Count = 0 Then
            ' There were no suitable feeds, hence get default feeds from resources.
            System.Diagnostics.Debug.Print("There were no suitable feeds, hence get default feeds from resources.")

            Dim rssFeed As RssFeed = rssFeed.FromText(C4F.DevKit.RSS.ScreenSaverWPF.ResourcesWrapper.DefaultRSSText)
            newRssFeeds.Add(rssFeed)
        End If

        Me._rssFeeds = newRssFeeds
        ' reset current indexes
        Me._currentFeedIndex = -1
        Me._currentItemIndex = -1
        MoveNext()
        Me._lastRefresh = loadstart
    End Sub

    Public ReadOnly Property Count() As Integer
        Get
            Return Me._rssFeeds.Count
        End Get
    End Property

    Public Function GetFeed(ByVal index As Integer) As RssFeed
        Return Me._rssFeeds(index)
    End Function

    Public ReadOnly Property CurrentFeed() As RssFeed
        Get
            Return Me._rssFeeds(_currentFeedIndex)
        End Get
    End Property
    Public ReadOnly Property CurrentFeedIndex() As Integer
        Get
            Return Me._currentFeedIndex
        End Get
    End Property
    Public ReadOnly Property CurrentItem() As RssItem
        Get
            Return Me._rssFeeds(Me._currentFeedIndex).Items(CurrentItemIndex)
        End Get
    End Property
    Public ReadOnly Property CurrentItemIndex() As Integer
        Get
            Return Me._currentItemIndex
        End Get
    End Property


    Public Sub MoveNext()
        If Me._rssFeeds Is Nothing OrElse Me._rssFeeds.Count = 0 Then
            Return
        End If

        ' If we don't have a currentFeed then pick a feed and image
        If Me._currentFeedIndex = -1 Then
            ' Pick the first feed & image
            Me._currentFeedIndex = 0
            Me._currentItemIndex = 0
        Else
            ' Increment next item
            Me._currentItemIndex += 1

            ValidateIndexes()
        End If
    End Sub

    Public Sub MovePrevious()
        If Me._rssFeeds Is Nothing OrElse Me._rssFeeds.Count = 0 Then
            Return
        End If

        Me._currentItemIndex -= 1

        If currentItemIndex < 0 Then
            ' Return to the previous feed
            Me._currentFeedIndex -= 1

            If Me._currentFeedIndex < 0 Then
                Me._currentFeedIndex = Me._rssFeeds.Count - 1
            End If

            Me._currentItemIndex = Me._rssFeeds(Me._currentFeedIndex).Items.Count - 1
        End If
    End Sub

    Private Sub ValidateIndexes()
        ' If we are at the end of the feed jump to the next feed
        If CurrentItemIndex >= Me._rssFeeds(Me._currentFeedIndex).Items.Count Then
            Me._currentItemIndex = 0

            ' We also need to go to the next feed
            Me._currentFeedIndex += 1

            ' If we are at the end of the feeds jump to the first feed
            If Me._currentFeedIndex >= _rssFeeds.Count Then
                Me._currentFeedIndex = 0
            End If
        End If
    End Sub
End Class